home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
docs
/
complex
/
complex.h
< prev
next >
Wrap
C/C++ Source or Header
|
2000-05-21
|
8KB
|
363 lines
/* 複素数演算マクロ集 */
/* 2000.05.21 by M.Kamada */
#include <math.h>
#include <setjmp.h>
/* 演算を続行できなくなったときのためにsetjmp(cjmpenv)で環境を準備しておくこと */
jmp_buf cjmpenv;
/* setjmp(cjmpenv)の返却値 */
#define C_DIVIDE_BY_ZERO 1 /* 0で除算しようとした */
#define C_ARG_ZERO 2 /* 0の角度を求めようとした */
#ifndef __GNUC__
#error "Sorry, GCC only"
#endif
#if __GNUC__==2
#define complex __complex__
#define Re(z) (__real__ (z))
#define Im(z) (__imag__ (z))
#else
typedef struct {
double re;
double im;
} complex;
#define Re(z) ((z).re)
#define Im(z) ((z).im)
#endif
#define tocomplex(r,i) \
({ \
complex _z_; \
Re(_z_) = (r); \
Im(_z_) = (i); \
_z_; \
})
#if __GNUC__==2
#define C_1I (1.0i)
#define C_2I (2.0i)
#define C_3I (3.0i)
#define C_4I (4.0i)
#define C_5I (5.0i)
#define C_6I (6.0i)
#else
#define C_1I tocomplex(0.0, 1.0)
#define C_2I tocomplex(0.0, 2.0)
#define C_3I tocomplex(0.0, 3.0)
#define C_4I tocomplex(0.0, 4.0)
#define C_5I tocomplex(0.0, 5.0)
#define C_6I tocomplex(0.0, 6.0)
#endif
#define C_2PI (6.28318530717958647692528676656) /* 2*pi */
#define C_PI (3.14159265358979323846264338328) /* pi */
#define C_PI_2 (1.57079632679489661923132169164) /* pi/2 */
#define C_PI_4 (0.78539816339744830961566084582) /* pi/4 */
#define C_1_PI (0.318309886183790671537767526745) /* 1/pi */
#define C_2_PI (0.63661977236758134307553505349) /* 2/pi */
#define C_2_SQRTPI (1.12837916709551257389615890312) /* 2/sqrt(pi) */
#define C_E (2.71828182845904523536028747135) /* e */
#define C_LN10 (2.30258509299404568401799145468) /* ln(10) */
#define C_LN2 (0.693147180559945309417232121458) /* ln(2) */
#define C_LOG10E (0.434294481903251827651128918917) /* log10(e) */
#define C_LOG2E (1.442695040888963407359924681) /* log2(e) */
#define C_SQRT1_2 (0.707106781186547524400844362105) /* 1/sqrt(2) */
#define C_SQRT2 (1.41421356237309504880168872421) /* sqrt(2) */
#define C_SQRT3 (1.73205080756887729352744634151) /* sqrt(3) */
#define C_SQRT5 (2.23606797749978969640917366873) /* sqrt(5) */
#define C_SQRT6 (2.44948974278317809819728407471) /* sqrt(6) */
#define C_SQRT7 (2.64575131106459059050161575364) /* sqrt(7) */
#define C_SQRT8 (2.82842712474619009760337744842) /* sqrt(8) */
#define C_SQRT10 (3.16227766016837933199889354443) /* sqrt(10) */
/* xの実数部にsを加える */
#if __GNUC__==2
#define creadd(x,s) ((x)+(s))
#else
#define creadd(x,s) \
({ \
complex _z_ = (x); \
Re(_z_) += (s); \
_z_; \
})
#endif
/* xの虚数部にsを加える */
#define cimadd(x,s) \
({ \
complex _z_ = (x); \
Im(_z_) += (s); \
_z_; \
})
/* xの実数部からsを引く */
#if __GNUC__==2
#define cresub(x,s) ((x)-(s))
#else
#define cresub(x,s) \
({ \
complex _z_ = (x); \
Re(_z_) -= (s); \
_z_; \
})
#endif
/* xの虚数部からsを引く */
#define cimsub(x,s) \
({ \
complex _z_ = (x); \
Im(_z_) -= (s); \
_z_; \
})
/* xの実数s倍 */
#if __GNUC__==2
#define cremul(x,s) ((x)*(s))
#else
#define cremul(x,s) \
({ \
complex _z_ = (x); \
double _s_ = (s); \
Re(_z_) *= _s_; \
Im(_z_) *= _s_; \
_z_; \
})
#endif
/* xの虚数s*i倍 */
#define cimmul(x,s) \
({ \
complex _z_; \
complex _x_ = (x); \
double _s_ = (s); \
Re(_z_) = Im(_x_) * (-_s_); \
Im(_z_) = Re(_x_) * _s_; \
_z_; \
})
/* xのスカラーs倍 */
#if __GNUC__==2
#define cscal(x,s) ((x)*(s))
#else
#define cscal(x,s) \
({ \
complex _z_ = (x); \
double _s_ = (s); \
Re(_z_) *= _s_; \
Im(_z_) *= _s_; \
_z_; \
})
#endif
/* xの共役複素数 */
#if __GNUC__==2
#define conj(x) (~((__complex__)(x)))
#else
#define conj(x) \
({ \
complex _z_ = (x); \
Im(_z_) = -Im(_z_); \
_z_; \
})
#endif
/* xの絶対値の2乗 */
#define cabs2(x) \
({ \
complex _x_ = (x); \
Re(_x_) * Re(_x_) + Im(_x_) * Im(_x_); \
})
/* xの絶対値 */
#define cabs(x) \
({ \
complex _x_ = (x); \
sqrt(Re(_x_) * Re(_x_) + Im(_x_) * Im(_x_)); \
})
/* xの角度 */
#define carg(x) \
({ \
complex _x_ = (x); \
if (Re(_x_) == 0.0 && Im(_x_) == 0.0) { \
longjmp(cjmpenv, C_ARG_ZERO); \
} \
atan2(Im(_x_), Re(_x_)); \
})
/* x+y */
#if __GNUC__==2
#define cadd(x,y) ((x)+(y))
#else
#define cadd(x,y) \
({ \
complex _z_ = (x); \
complex _y_ = (y); \
Re(_z_) += Re(_y_); \
Im(_z_) += Im(_y_); \
_z_; \
})
#endif
/* x-y */
#if __GNUC__==2
#define csub(x,y) ((x)-(y))
#else
#define csub(x,y) \
({ \
complex _z_ = (x); \
complex _y_ = (y); \
Re(_z_) -= Re(_y_); \
Im(_z_) -= Im(_y_); \
_z_; \
})
#endif
/* x*y */
#if __GNUC__==2
#define cmul(x,y) ((x)*(y))
#else
#define cmul(x,y) \
({ \
complex _z_; \
complex _x_ = (x); \
complex _y_ = (y); \
Re(_z_) = Re(_x_) * Re(_y_) - Im(_x_) * Im(_y_); \
Im(_z_) = Re(_x_) * Im(_y_) + Im(_x_) * Re(_y_); \
_z_; \
})
#endif
/* x/y */
#define cdiv(x,y) \
({ \
complex _z_; \
complex _x_ = (x); \
complex _y_ = (y); \
double _r2_; \
if ((_r2_ = cabs2(_y_)) == 0.0) { \
longjmp(cjmpenv, C_DIVIDE_BY_ZERO); \
} \
Re(_z_) = (Re(_x_) * Re(_y_) + Im(_x_) * Im(_y_)) / _r2_; \
Im(_z_) = (Im(_x_) * Re(_y_) - Re(_x_) * Im(_y_)) / _r2_; \
_z_; \
})
/* xの2乗 (a+bi)^2=aa+2abi-bb */
#define cpow2(x) \
({ \
complex _z_; \
complex _x_ = (x); \
Re(_z_) = Re(_x_) * Re(_x_) - Im(_x_) * Im(_x_); \
Im(_z_) = (Re(_x_) * Im(_x_)) * 2.0; \
_z_; \
})
/* xの3乗 (a+bi)^3=aaa+3aabi-3abb-bbbi */
#define cpow3(x) \
({ \
complex _z_; \
complex _x_ = (x); \
double _aa_, _bb_; \
_aa_ = Re(_x_) * Re(_x_); \
_bb_ = Im(_x_) * Im(_x_); \
Re(_z_) = Re(_x_) * (_aa_ - 3.0 * _bb_); /* aaa-3abb */ \
Im(_z_) = Im(_x_) * (3.0 * _aa_ - _bb_); /* 3aab-bbb */ \
_z_; \
})
/* xの4乗 (a+bi)^4=aaaa+4aaabi-6aabb-4abbbi+bbbb */
#define cpow4(x) \
({ \
complex _z_; \
complex _x_ = (x); \
double _aa_, _bb_, _ab_; \
_aa_ = Re(_x_) * Re(_x_); \
_bb_ = Im(_x_) * Im(_x_); \
_ab_ = Re(_x_) * Im(_x_); \
Re(_z_) = _aa_ * (_aa_ - 6.0 * _bb_) + _bb_ * _bb_; /* aaaa-6aabb+bbbb */ \
Im(_z_) = 4.0 * _ab_ * (_aa_ - _bb_); /* 4aaab-4abbb */ \
_z_; \
})
/* xの5乗 (a+bi)^5=aaaaa+5aaaabi-10aaabb-10aabbbi+5abbbb+bbbbbi */
#define cpow5(x) \
({ \
complex _z_; \
complex _x_ = (x); \
double _aa_, _bb_, _ab_, _aaa_, _bbb_; \
_aa_ = Re(_x_) * Re(_x_); \
_bb_ = Im(_x_) * Im(_x_); \
_ab_ = Re(_x_) * Im(_x_); \
_aaa_ = _aa_ * Re(_x_); \
_bbb_ = _bb_ * Im(_x_); \
Re(_z_) = _aaa_ * (_aa_ - 10.0 * _bb_) + 5.0 * _ab_ * _bbb_; /* aaaaa-10aaabb+5abbbb */ \
Im(_z_) = 5.0 * _aaa_ * _ab_ + _bbb_ * (_bb_ - 10.0 * _aa_); /* 5aaaab+bbbbb-10aabbb */ \
_z_; \
})
/* xの6乗 (a+bi)^6=aaaaaa+6aaaaabi-15aaaabb-20aaabbbi+15aabbbb+6abbbbbi-bbbbbb */
#define cpow6(x) \
({ \
complex _z_; \
complex _x_ = (x); \
double _aa_, _bb_, _ab_, _aaaa_, _bbbb_; \
_aa_ = Re(_x_) * Re(_x_); \
_bb_ = Im(_x_) * Im(_x_); \
_ab_ = Re(_x_) * Im(_x_); \
_aaaa_ = _aa_ * _aa_; \
_bbbb_ = _bb_ * _bb_; \
Re(_z_) = _aa_ * (_aa_ * (_aa_ - 15.0 * _bb_) + 15.0 * _bbbb_) - _bb_ * _bbbb_; /* aaaaaa-15aaaabb+15aabbbb-bbbbbb */ \
Im(_z_) = _ab_ * (6.0 * (_aaaa_ + _bbbb_) - 20.0 * _aa_ * _bb_); /* 6aaaaab+6abbbbb-20aaabbb */ \
_z_; \
})
/* xのe乗 */
#define cpow(x,e) \
({ \
complex _z_ = (x); \
double _e_ = (e); \
double _r_, _t_; \
_r_ = pow(cabs(_z_), _e_); \
_t_ = carg(_z_) * _e_; \
Re(_z_) = _r_ * cos(_t_); \
Im(_z_) = _r_ * sin(_t_); \
_z_; \
})
/* xのm番目のn乗根 */
#define crot(x,n,m) \
({ \
complex _z_ = (x); \
int _n_ = (n); \
double _r_, _t_; \
_r_ = pow(cabs(_z_), 1.0 / (double)_n_); \
_t_ = carg(_z_) + C_2PI * (double)(m) / (double)_n_; \
Re(_z_) = _r_ * cos(_t_); \
Im(_z_) = _r_ * sin(_t_); \
_z_; \
})
/* 距離の2乗 */
#define cdist2(x,y) \
({ \
complex _x_ = (x); \
complex _y_ = (y); \
double _r_ = Re(_x_) - Re(_y_); \
double _i_ = Im(_x_) - Im(_y_); \
_r_ * _r_ + _i_ * _i_; \
})
/* 距離 */
#define cdist(x,y) \
({ \
complex _x_ = (x); \
complex _y_ = (y); \
double _r_ = Re(_x_) - Re(_y_); \
double _i_ = Im(_x_) - Im(_y_); \
sqrt(_r_ * _r_ + _i_ * _i_); \
})